/**
 * Author: Todd Kerpelman
 * Date: 5/17/12
 * Time: 3:27 PM
 *
 * Copyright 2012 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package net.kerp.hangoutSpace {

import Box2D.Collision.Shapes.b2PolygonShape;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2DebugDraw;
import Box2D.Dynamics.b2FixtureDef;
import Box2D.Dynamics.b2World;

import net.kerp.hangoutSpace.Events.HangoutEvent;

import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;


[SWF(width="640", height="480", backgroundColor="#555555", frameRate="30")]
public class HangoutInSpace extends Sprite {
  private var _world:b2World;
  private var _background:SpaceBackground;
  private var _physObjs:Array;
  private var _peopleManager:PeopleManager;
  private var _hangoutCommunicator:HangoutCommunicator;

  public static const HANGOUT_WIDTH:int = 640;
  public static const HANGOUT_HEIGHT:int = 480;
  public static const RATIO:Number = 30.0;
  private var _spaceTrails:SpaceTrails;

  public function HangoutInSpace() {
    var spaceWind:SpaceWind = new SpaceWind();
    _background = new SpaceBackground(HANGOUT_WIDTH, HANGOUT_HEIGHT, spaceWind);
    addChild(_background);
    setupWorld();
    setupBoundaryWalls();
    _spaceTrails = new SpaceTrails(spaceWind);
    addChild(_spaceTrails);
    _physObjs = [];
    _peopleManager = new PeopleManager();
    _peopleManager.addEventListener(HangoutEvent.PARTICIPANT_ADDED, onFloaterAdded);
    _peopleManager.addEventListener(HangoutEvent.PARTICIPANT_REMOVED, onFloaterRemoved);
    _hangoutCommunicator = new HangoutCommunicator(_peopleManager);
    _hangoutCommunicator.initApp();

    // setupDebugDraw();

    addEventListener(Event.ENTER_FRAME, updateStuff);
    addEventListener(MouseEvent.CLICK, onClick)
  }

  private function onClick(event:MouseEvent):void {
    var mouseClick:b2Vec2 = new b2Vec2(event.stageX / RATIO, event.stageY / RATIO);
    trace("Mouseclick at " + mouseClick.x + ", " + mouseClick.y);
    for each (var nextObj:FloatyPerson in _physObjs) {
      nextObj.mouseClickAt(mouseClick);
    }
  }

  private function onFloaterRemoved(event:HangoutEvent):void {
    var goingAway:HangoutParticipant = event.person;
    for (var j:int=_physObjs.length-1; j>=0; j--) {
      if ((_physObjs[j] as FloatyPerson).hangoutUser.id == goingAway.id) {
        (_physObjs[j] as FloatyPerson).goAway();
        _physObjs.splice(j,  1);
      }
    }

  }

  private function onFloaterAdded(event:HangoutEvent):void {
    var newParticipant:HangoutParticipant = event.person;
    var newFloater:FloatyPerson = new FloatyPerson(_world, newParticipant);
    _physObjs.push(newFloater);
    addChild(newFloater);
  }

  private function updateStuff(event:Event):void {
    _world.Step(1/30, 10, 10);
    _world.DrawDebugData();
    var _trailData:Array = [];
    for each (var nextFloater:FloatyPerson in _physObjs) {
      nextFloater.updateyourself();
      _trailData.push(nextFloater.getTrailData());
    }
    _spaceTrails.addDots(_trailData);


  }



  private function setupDebugDraw():void {
    var canvas:Sprite = new Sprite();
    addChild(canvas);
    var artist:b2DebugDraw = new b2DebugDraw();
    artist.SetSprite(canvas);
    artist.SetDrawScale(RATIO);
    artist.SetFillAlpha(0.5);
    artist.SetLineThickness(2.0);
    artist.SetFlags(b2DebugDraw.e_shapeBit);
    _world.SetDebugDraw(artist);
  }
  

  private function setupBoundaryWalls():void {
    // Create the top wall
    var horizBar:b2PolygonShape = new b2PolygonShape();
    horizBar.SetAsBox(HANGOUT_WIDTH / 2 / RATIO, 4 / RATIO)

    var fixtureDef:b2FixtureDef = new b2FixtureDef();
    fixtureDef.density = 1.0;
    fixtureDef.friction = 0.0;
    fixtureDef.restitution = 0.6;
    fixtureDef.shape = horizBar;

    var bodyDef:b2BodyDef = new b2BodyDef();
    bodyDef.position = new b2Vec2(HANGOUT_WIDTH / 2 / RATIO, 4 / RATIO )
    var topWall:b2Body = _world.CreateBody(bodyDef);
    topWall.CreateFixture(fixtureDef);

    // Now create the bottom wall
    bodyDef.position.y = (HANGOUT_HEIGHT - 4) / RATIO;
    var bottomWall:b2Body = _world.CreateBody(bodyDef);
    bottomWall.CreateFixture(fixtureDef);

    // Create the left wall
    var vertBar:b2PolygonShape = new b2PolygonShape();
    vertBar.SetAsBox(4/ RATIO, HANGOUT_HEIGHT /2 / RATIO );

    fixtureDef.shape = vertBar;
    bodyDef.position = new b2Vec2(4 / RATIO, HANGOUT_HEIGHT / 2 / RATIO);

    var leftWall:b2Body = _world.CreateBody(bodyDef);
    leftWall.CreateFixture(fixtureDef);

    bodyDef.position.x = (HANGOUT_WIDTH - 4) / RATIO;
    var rightWall:b2Body = _world.CreateBody(bodyDef);
    rightWall.CreateFixture(fixtureDef);

  }

  private function setupWorld():void {
    var gravity:b2Vec2 = new b2Vec2(0.0, 0.0);
    var ignoreSleeping:Boolean = true;

    _world = new b2World(gravity, ignoreSleeping);

  }


}



}
